

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package RS;

/**
 * Alpha Generator class for RSEncoder function
 * @author Heli Wang
 */
class Combination {

    Combination(){

    }

    /**
     * Generates the alpha exponents of the generator polynomial.
     * @param length Length of the polynomial.
     * @return Alpha exponents of the generator polynomial, from x^n at pos 0 to x^0 at pos n.
     */
    static int[] getAlpha(int length){
        int[] exponents = new int[length+1];
        exponents[0]=0;
        for (int i=1;i<exponents.length;i++){
            exponents[i]=alphaGen(length,i);
        }
        return exponents;
    }

    /**
     * Generates the alpha exponent for the given generator polynomial
     * @param length Length of the generator polynomial
     * @param n Position of exponent in the polynomial, non-zero.
     * @return The exponent for the alpha at n.
     */
    private static int alphaGen(int length, int n){
        int a=0, b=0; //exponent form
        if (n==0){
            return 0;
        } else {
            int[] key = new int[length];//TO HELI:the arrays "key" and "iter" are both initialized but all values are set to zero. i believe that this is why you are having logical errors
            for (int i=0;i<key.length;i++){
                key[i]=i;
            }

            int[] iter = new int[n];
            for (int i=0;i<iter.length;i++){
                iter[i]=i;
            }

            //primary iteration
            for (int c : iter){
                b += key[c];
            }
            a = b;
            //iteration loop
            while (!iterFinished(key.length, iter)){//i see possible logical errors but im not quite sure what this does or how it works
                iterate(key.length, iter,iter.length);
                //read
                b=0;
                for (int c : iter){
                    b += key[c];
                }
                a = galoisSum(a,b);
            }
            return a;
        }
    }

    /**
     * Iterates the iteration array
     * @param keyLength Length of the key array
     * @param iter The original iteration array
     * @param n Iteration placeholder - start with iter.length
     */
    private static void iterate(int keyLength, int[] iter, int n){
        if (!iterFinished(keyLength, iter)){
            iter[iter.length-1] += 1;
            iterRecur(keyLength,iter,iter.length-1);
        }
    }

    /**
     * Adjusts the updated the iteration array.
     * @param keyLength Length of the key array
     * @param iter The original iteration array
     * @param n Iteration placeholder - start with iter.length
     */
    private static void iterRecur(int keyLength, int[] iter, int n){
        if (iter[n] >= keyLength){
            iter[n-1]+=1;
            iterRecur(keyLength,iter,n-1);
            iter[n] = iter[n-1]+1;
            iterRecur(keyLength,iter,n);
        }
    }

    /**
     * Checks whether the iteration array has reached the end.
     * @param keyLength Length of the key array.
     * @param iter The original iteration array.
     * @return Returns whether the iteration array is finished.
     */
    private static boolean iterFinished(int keyLength, int[] iter){
        boolean test = true;
        for (int i=iter.length-1;i>=0;i--){
            if (iter[i]!=keyLength-1 - (iter.length-1 - i)){
                test = false;
            }
        }
        return test;
    }
    /**
     * Takes two alpha exponents and bit-adds them.
     * @param a First exponent
     * @param b Second exponent
     * @return XOR sum of a and b, in exponent form.
     */
    private static int galoisSum(int a, int b){
        int x,y,z;
        x = PolyGenerator.expToIntFilter(a);
        y = PolyGenerator.expToIntFilter(b);
        z = x^y;
        return PolyGenerator.intToExp(z);
    }

}
